import { MessagePluginManager } from '.';
import { MessageEvent, Message } from '..';
import { ChatStatus, MessageInfo, OutputStatus, SendParams } from '../type';
import { isEndChuns } from '../dispose';
import { isString } from '@tarojs/shared';
import { jsonParse } from '@material/helpers';

export class AiStreamPlugin implements MessagePluginManager {
    name: string;
    chatStatus: ChatStatus;
    chatInfo: {
        id: string | number;
        content: string[];
        chunId: number;
    };

    transformEvent: boolean;

    constructor() {
        this.name = 'AiStreamPlugin';
        this.chatStatus = 'ai';
        this.chatInfo = {
            id: 0,
            content: [],
            chunId: 0
        };
        this.transformEvent = true;
    }
    beforeSend(params: SendParams) {
        const { chatStatus = 'ai', transformEvent = true } = params;
        this.chatStatus = chatStatus;
        this.transformEvent = transformEvent;
        return params;
    }
    startSend(params: SendParams, context: Message) {
        const { Content, ExtInfo, MsgType } = params;
        if (MsgType !== 'event' && FromType === 'user') {
            context.setOutputStatus(OutputStatus.InputStart);
            context.triggerHook(MessageEvent.Message, {
                Content,
                ExtInfo: isString(ExtInfo) ? jsonParse(ExtInfo) : ExtInfo,
                FromType: 'user',
                chatStatus: this.chatStatus,
                id: context.autoSumId(),
                outputStatus: OutputStatus.InputStart,
                MsgType,
                Sender: '',
                MsgId: '',
                MsgTime: Date.now(),
                To: 'AGENT'
            });
        }
        return params;
    }

    transformUserInfo(info: MessageInfo, context: Message) {
        if (info.FromType === 'user' && this.transformEvent && this.chatStatus === 'ai') {
            this.chatInfo.content = [];
            this.chatInfo.chunId = 0;
            this.chatInfo.id = info.MsgId || info.ExtInfo?.msg_id || this.chatInfo.id || '';
            context.setOutputStatus(OutputStatus.InputEnd);
            context.triggerHook(MessageEvent.Message, {
                ...info,
                chatStatus: this.chatStatus,
                outputStatus: OutputStatus.InputEnd,
                id: context.autoSumId()
            });
            context.setOutputStatus(OutputStatus.OutputLoading);
            context.triggerHook(MessageEvent.Message, {
                Content: [],
                outputType: '',
                FromType: '',
                From: 'ai',
                chatStatus: this.chatStatus,
                outputStatus: OutputStatus.OutputLoading,
                messgeId: this.chatInfo.id,
                id: context.autoSumId()
            });
            return false;
        }
    }
    transformAIInfo(info: MessageInfo, context: Message) {
        if (
            info.FromType !== 'user' &&
            info.From === 'ai' &&
            this.transformEvent &&
            this.chatStatus === 'ai'
        ) {
            const endType = isEndChuns(info);
            const [outputStatus, content] = context.outputTransformStatus(endType, info);
            if (!outputStatus) {
                return false;
            }
            if (endType !== 'sensitive') {
                this.chatInfo.content.push(content);
            }
            if (endType === 'sensitive') {
                this.chatInfo.content = content;
            }
            context.triggerHook(MessageEvent.Message, {
                ...info,
                Content: this.chatInfo.content,
                outputType: endType,
                chatStatus: this.chatStatus,
                outputStatus,
                messgeId:
                    this.chatInfo.chunId > 0
                        ? `${this.chatInfo.id}-${this.chatInfo.chunId}`
                        : this.chatInfo.id,
                id: context.uuid
            });
            if (outputStatus === OutputStatus.OutputEnd) {
                this.chatInfo.content = [];
                context.autoSumId();
                this.chatInfo.chunId = this.chatInfo.chunId + 1;
            }
            return false;
        }
    }

    beforeReceive(info: MessageInfo, context: Message) {
        const isUserContinue = this.transformUserInfo(info, context);
        if (isUserContinue === false) {
            return false;
        }
        const isAIContinue = this.transformAIInfo(info, context);

        if (isAIContinue === false) {
            return false;
        }

        return info;
    }
}
